package main

import (
	"fmt"
	"sort"
)

// map[k]v, map[k1]map[k2]v
func declareMap() {

	// 当前声明的m为nil map，无法直接使用,不会分配内存空间
	var m map[string]int
	m1 := map[string]int{}
	m2 := map[string]int{"1": 1, "2": 2, "3": 3} // key和value可以是任何类型
	fmt.Println(m, m1, m2)

	// 使用make初始化之后可正常使用，注意：如果没有初始化可以get, del,但是不能put
	m = make(map[string]int, 2)

	m = make(map[string]int) // 也可以不定义长度
	// 朝m里面放一个键为one，值为1的键值对数据
	m["one"] = 1
	m["two"] = 2
	// 取出键为one对应的值
	fmt.Println(m["one"])
	towVal, ok := m["two"]
	if ok {
		fmt.Println(towVal, ok)
	} else {
		fmt.Println("two value不存在")
	}
}

// 会在所有方法执行之前执行
func init() {
	m := map[string]int{"one": 1, "two": 2, "three": 3}
	fmt.Println(m)

	// 双层map
	a := make(map[string]map[int]string) // empty map
	var m2 map[string]int                // m3 == nil
	fmt.Println(a, m2)
	a["class1"] = make(map[int]string, 3)
	a["class1"][01] = "露露"
	a["class1"][02] = "丽丽"
	a["class1"][02] = "菲菲"
	a["class2"] = make(map[int]string, 3)
	a["class2"][01] = "小明"
	a["class2"][02] = "小龙"
	a["class2"][02] = "小飞"
	for k1, v1 := range a {
		fmt.Println(k1)
		for k2, v2 := range v1 {
			fmt.Println("%v,%v \n", k2, v2)
		}
	}
}

func forMap() { // map只有forRange 遍历
	m := map[string]int{"one": 1, "two": 2}
	for key, val := range m {
		m[key] = val + val // 修改的是map的值
		fmt.Printf("键%s对应的值为%d \n", key, m[key])
	}
	for key := range m {
		fmt.Printf("键%s对应的值为%d \n", key, m[key])
	}
}

func existMap() {
	m := map[string]int{"zero": 0, "one": 1, "two": 2}
	value, ok := m["zero"] // ok 接收看key是否存在
	if ok {
		fmt.Println("zero存在，value：", value)
	} else {
		fmt.Println("zero不存在，value：", value)
	}
	value, ok = m["three"]
	if ok {
		fmt.Println("three存在，value：", value)
	} else {
		fmt.Println("three不存在，value：", value)
	}
}

func delMap() {
	m := map[string]int{"zero": 0, "one": 1, "two": 2}
	// 删除m中key为two的元素
	delete(m, "two")
	value, ok := m["two"]
	if ok {
		fmt.Println(value)
	} else {
		fmt.Println("two不存在")
	}
}

func lenMap() {
	m := map[string]int{"one": 1, "two": 2, "three": 3}
	i := len(m)
	fmt.Println(i)
}

var m1 map[string]float32 = map[string]float32{"C": 5, "Go": 4.5, "Python": 4.5, "C++": 2}

func mapStruct() {

	m2 := map[string]float32{"C": 5, "Go": 4.5, "Python": 4.5, "C++": 2}
	m3 := map[int]struct {
		name string
		age  int
	}{
		1: {"user1", 10}, // 可省略元素类型。
		2: {"user2", 20},
	}
	fmt.Printf("全局变量 map m1 : %v\n", m1)
	fmt.Printf("局部变量 map m2 : %v\n", m2)
	fmt.Printf("局部变量 map m3 : %v\n", m3)
}

func sortMap() {
	m := map[string]int{"c": 3, "a": 1, "b": 2, "f": 6, "d": 4, "e": 5, "y": 7}
	var slice []string
	for k, _ := range m {
		slice = append(slice, k)
	}
	fmt.Println("slice string is", slice)
	sort.Strings(slice)
	fmt.Println("slice string sort is ", slice)
	for _, s := range slice {
		fmt.Println(m[s])
	}
}

func mapStructVal() {
	/*结构体值类型*/
	type user struct {
		name string
	}
	m := map[int]user{
		1: {name: "张三"},
	}
	fmt.Println(m)
	u := m[1]
	u.name = "tom"
	m[1] = u
	fmt.Println(m)

	/*结构体指针类型*/
	m2 := map[int]*user{
		1: {name: "小五"},
	}
	m2[1].name = "jack"
	fmt.Println(m2[1].name)
}

func main() {
	mapStructVal()
}
